<template>
	<div class="layout-container">
		<div class="layout-header">
			<DesignHeader :zoom="zoom"></DesignHeader>
		</div>
		<div class="layout-content">
			<!-- 功能区 -->
			<div class="layout-aside-left">
				<DesignPanel :list="complexList" />
			</div>
			<div class="layout-main">
				<div class="clear-rluer"></div>
				<!-- 选框 -->
				<DesignMenu :config="contextMenu" />
				<div ref="screen" id="screen" class="desgin-canvas" v-resize="handleResize"
					@mousedown="mousedownDesign">
					<!-- 顶部标尺数字绘制 -->
					<div class="v-ruler-canvas-content">
						<canvas ref="v-ruler-canvas" :width="criterion.width" height="20" />
					</div>
					<!-- 画布区域 -->
					<div class="design-content" :style="designStyle(layoutConfig)" @drop="handleDrop"
						@dragover="handleDragOver">
						<DesignView :complex-list="complexList" :complexItem="complexItem" :zoom="layoutConfig.scale" />
					</div>

					<!-- 侧边标尺数字绘制 -->
					<div class="h-ruler-canvas-content">
						<canvas ref="h-ruler-canvas" :height="criterion.height" width="20" />
					</div>
				</div>
			</div>
			<!-- 组件属性 -->
			<div class="layout-aside-right">
				<DesignAttribute />
			</div>
		</div>
	</div>
</template>

<script>
	import DesignMenu from './components/DesignMenu'
	import DesignPanel from './components/DesignPanel'
	import DesignAttribute from './components/DesignAttribute'
	import DesignView from './components/DesignView'
	import DesignHeader from './components/Header'
	export default {
		components: {
			DesignAttribute,
			DesignPanel,
			DesignView,
			DesignMenu,
			DesignHeader
		},
		directives: {
			resize: {
				bind(e, binding) {
					// console.log("绑定");
					let width = 0;
					let height = 0;
					const isReize = () => {
						let offsetWidth = e.offsetWidth;
						let offsetHeight = e.offsetHeight;
						if (width !== offsetWidth || height !== offsetHeight) {
							const value = {
								width: offsetWidth,
								height: offsetHeight
							}
							binding.value(value);
						}
						width = offsetWidth;
						height = offsetHeight;
					}
					e.__vueSetInterval__ = setInterval(isReize, 300);
				},
				unbind(e) {
					// console.log("解绑");
					clearInterval(e.__vueSetInterval__);
				}
			}
		},
		data() {
			return {
				index: 0,
				// 编辑器
				criterion: {
					width: 3000,
					height: 3000,
				},
				// 画布尺寸
				layoutConfig: {
					width: 1920, // 宽度
					height: 1080, // 高度
					left: 0,
					top: 0,
					scale: 0.5
				},
				complexItem: null,
				complexList: this.$store.state.design.complexData,
				keyCode: {
					ctrl: false,
					space: false,
					plus: false,
					cut: false,
					delete: false
				}
			}
		},
		computed: {
			// 右键菜单
			contextMenu() {
				return this.$store.state.design.contextMenu;
			},
			zoom() {
				return (this.layoutConfig.scale * 100).toFixed(0);
			},
		},
		created() {
			document.oncontextmenu = function() {
				return false;
			}
			window.addEventListener("keyup", this.handleKeyup);
			window.addEventListener("keydown", this.handleKeydown);
		},
		beforeDestroy() {
			// 在组件生命周期结束的时候销毁。
			window.removeEventListener("keyup", this.handleKeyup, false);
			window.removeEventListener("keydown", this.handleKeydown, false);
		},
		mounted() {
			this.setScreenCenter();
			this.drawRulerX();
			this.drawRulerY();
		},
		methods: {
			designStyle(style) {
				return {
					width: `${style.width}px`,
					height: `${style.height}px`,
					transform: `translate(${style.left}px, ${style.top}px) scale(${style.scale}, ${style.scale})`,
				}
			},
			// 键盘按下事件
			handleKeydown() {
				document.onkeydown = (e) => {
					//事件对象兼容
					let el = e || window.event || arguments.callee.caller.arguments[0];
					// console.log(el.keyCode)
					//键盘按键判断:左箭头-37;上箭头-38；右箭头-39;下箭头-40  回车：13   ctrl：17   shift：16
					if (el.keyCode == 17) {
						e.preventDefault();
						this.keyCode.ctrl = true;
						// return false;
					}

					if (el.keyCode == 107) {
						e.preventDefault();
						this.keyCode.plus = true;
						this.setScale('plus')
					}

					if (el.keyCode == 109) {
						e.preventDefault();
						this.keyCode.cut = true;
						this.setScale('cut')
					}

					if (el.keyCode == 32) {
						e.preventDefault();
						this.keyCode.space = true;
						document.getElementById('screen').style.cursor = 'grab';
					}
				};
			},
			setScale(type) {
				let _scale = 0.05;
				if (type === 'plus') {
					if (this.keyCode.plus) {
						if (this.layoutConfig.scale < 1) {
							this.layoutConfig.scale += _scale;
						} else {
							this.layoutConfig.scale = 1;
						}
					}
				}
				if (type === 'cut') {
					if (this.keyCode.cut) {
						if (this.layoutConfig.scale > 0.2) {
							this.layoutConfig.scale -= _scale;
						} else {
							this.layoutConfig.scale = 0.2;
						}
					}
				}
			},
			// 鼠标按下事件
			mousedownDesign(e) {
				const dom = document.getElementById('screen');
				const design = document.getElementById('design').getBoundingClientRect();
				// const dropX = e.clientX;
				// const dropY = e.clientY;

				// const move = (moveEvent) => {
				// 	const moveX = moveEvent.clientX;
				// 	const moveY = moveEvent.clientY - dropY;
				// }
				// const up = () => {
				// 	document.removeEventListener('mousemove', move)
				// 	document.removeEventListener('mouseup', up)
				// }
				// document.addEventListener('mousemove', move)
				// document.addEventListener('mouseup', up)
			},
			// 键盘松开事件
			handleKeyup() {
				document.onkeyup = (e) => {
					//事件对象兼容
					let el = e || window.event || arguments.callee.caller.arguments[0];
					//键盘按键判断:左箭头-37;上箭头-38；右箭头-39;下箭头-40  回车：13   ctrl：17   shift：16
					if (el.keyCode == 17) {
						// 取消默认事件
						e.preventDefault();
						this.keyCode.ctrl = false;
					}

					if (el.keyCode == 107) {
						e.preventDefault();
						this.keyCode.plus = false;
					}

					if (el.keyCode == 109) {
						e.preventDefault();
						this.keyCode.cut = false;
					}

					if (el.keyCode == 32) {
						e.preventDefault();
						this.keyCode.space = false;
						document.getElementById('screen').style.cursor = 'auto';
					}
				};
			},
			// 监听编辑器窗口大小
			handleResize(e) {
				// console.log(e)
				const rounding = (number) => {
					const digits = number.toString().length;
					let num = 0;
					if (digits > 1) {
						const unitsDigit = parseInt(number.toString()[digits - 1]);
						num = number - unitsDigit;
					}
					return num;
				}
				const dom = document.getElementById('screen');
				const offsetWidth = e.width;
				const offsetHeight = e.height;
				const scrollLeft = (this.criterion.width - dom.offsetWidth) / 2;
				const scrollTop = (this.criterion.height - dom.offsetHeight) / 2;
				dom.scrollLeft = scrollLeft;
				dom.scrollTop = scrollTop;
				const centerX = scrollLeft + (offsetWidth / 2 - this.layoutConfig.width / 2);
				const centerY = scrollTop + (offsetHeight / 2 - this.layoutConfig.height / 2);
				this.layoutConfig.left = rounding(centerX);
				this.layoutConfig.top = rounding(centerY);
			},
			// 设置画布相对编辑器窗口居中
			setScreenCenter() {
				const rounding = (number) => {
					const digits = number.toString().length;
					let num = 0;
					if (digits > 1) {
						const unitsDigit = parseInt(number.toString()[digits - 1]);
						num = number - unitsDigit;
					}
					return num;
				}
				const dom = document.getElementById('screen');
				const offsetWidth = dom.offsetWidth;
				const offsetHeight = dom.offsetHeight;
				const scrollLeft = (this.criterion.width - dom.offsetWidth) / 2;
				const scrollTop = (this.criterion.height - dom.offsetHeight) / 2;
				dom.scrollLeft = scrollLeft;
				dom.scrollTop = scrollTop;
				const centerX = scrollLeft + (offsetWidth / 2 - this.layoutConfig.width / 2);
				const centerY = scrollTop + (offsetHeight / 2 - this.layoutConfig.height / 2);
				this.layoutConfig.left = rounding(centerX);
				this.layoutConfig.top = rounding(centerY);
			},
			// 释放组件通过 store 添加
			handleDrop(e) {
				e.preventDefault()
				e.stopPropagation()
				const offset = {
					x: e.offsetX,
					y: e.offsetY
				}
				this.$store.dispatch("design/putComplex", offset)
			},
			// 拖拽元素
			handleDragOver(e) {
				e.preventDefault()
			},
			drawRulerX() {
				const zoom = this.layoutConfig.scale;
				const canvas = this.$refs["v-ruler-canvas"];
				const ctx = canvas.getContext("2d");
				ctx.clearRect(0, 0, canvas.width, canvas.height);
				ctx.lineWidth = 1;
				ctx.strokeStyle = "#bbb"; // 刻度颜色
				ctx.beginPath();
				// 画布居中
				let _width = this.layoutConfig.left;
				let y = 0;
				for (let i = 0; i <= this.criterion.width; i += 10) {
					const index = _width - i;
					let scale = Math.abs(index);
					let y = scale % 100 === 0 ? 12 : 6;
					if (index <= 0) {
						ctx.moveTo(scale + _width, y);
						ctx.lineTo(scale + _width, 0);
						ctx.stroke();
					}

					ctx.moveTo(i, y);
					ctx.lineTo(i, 0);
					ctx.stroke();

					if (scale % 100 === 0) {
						ctx.fillStyle = "#bbb";
						ctx.font = "5px";
						ctx.fillText((-1 * index).toString(), i + 4, 18);
					}
				}
			},
			drawRulerY() {
				const canvas = this.$refs["h-ruler-canvas"];
				const ctx = canvas.getContext("2d");
				ctx.clearRect(0, 0, canvas.width, canvas.height);
				ctx.lineWidth = 1;
				ctx.strokeStyle = "#bbb"; // 刻度颜色
				ctx.beginPath();
				// 画布居中
				let _height = this.layoutConfig.top;
				for (let i = 0; i < this.criterion.height; i += 10) {
					const index = _height - i;

					if (index <= 0) {
						let scale = Math.abs(index);
						let x = scale % 100 === 0 ? 12 : 6
						ctx.moveTo(0, scale + _height);
						ctx.lineTo(x, scale + _height);
						ctx.stroke();
						ctx.closePath();
						ctx.save();

						ctx.beginPath();
						if (scale % 100 === 0) {
							ctx.translate(12, scale + _height + 4);
							ctx.rotate((90 * Math.PI) / 180);
							ctx.fillStyle = "#bbb";
							ctx.font = "5px";
							ctx.fillText(scale.toString(), 0, 0);
							ctx.closePath();
							ctx.restore();
						}
					}


					if (index > 0) {
						let scale = Math.abs(index);
						let x = scale % 100 === 0 ? 12 : 6
						ctx.moveTo(0, i);
						ctx.lineTo(x, i);
						ctx.stroke();
						ctx.closePath();
						ctx.save();

						ctx.beginPath();
						if (scale % 100 === 0) {
							ctx.translate(12, i + 4);
							ctx.rotate((90 * Math.PI) / 180);
							ctx.fillStyle = "#bbb";
							ctx.font = "5px";
							ctx.fillText((-1 * index).toString(), 0, 0);
							ctx.closePath();
							ctx.restore();
						}
					}
				}
			},
		}
	}
</script>

<style scoped lang="scss">
	$bg-color: rgb(255, 255, 255);
	$border-color: rgb(219 219 219);

	.layout-container {
		width: 100%;
		height: 100vh;
		background: #f4f4f4;
		overflow: hidden;
	}

	.layout-header {
		position: relative;
		width: 100%;
		height: 48px;
		padding: 0px 16px;
		background: $bg-color;
		box-shadow: rgb(219 219 219) 0px 1px 0px;
		z-index: 1024;
	}

	.layout-content {
		width: 100%;
		height: calc(100% - 48px);
		display: flex;
		justify-content: space-between;

		.layout-aside-left {
			width: 244px;
			height: 100%;
			background: $bg-color;
			border-right: 1px solid $border-color;
		}

		.layout-main {
			flex: 1;
			height: 100%;
			overflow: hidden;


			#screen {
				position: relative;
				width: 100%;
				height: 100%;
				overflow: auto;
			}

			.clear-rluer {
				position: absolute;
				width: 15px;
				height: 15px;
				background-color: rgba(22, 132, 252, 0.3);
				border-right: 2px solid rgb(219, 219, 219);
				border-bottom: 2px solid rgb(219, 219, 219);
				z-index: 2044;
				cursor: pointer;
				box-sizing: border-box;

				&:hover {
					cursor: pointer;
				}
			}

			.v-ruler-canvas-content {
				position: sticky;
				top: 0;
				height: 16px;
				z-index: 1024;
			}

			.h-ruler-canvas-content {
				position: sticky;
				left: 0;
				width: 16px;
				z-index: 1024;
			}

			.design-content {
				position: absolute;
				background-color: #fff;
				border: 1px solid #eee;
				transform-origin: center center;
			}
		}

		.layout-aside-right {
			width: 240px;
			height: 100%;
			background: $bg-color;
			border-left: 1px solid $border-color;
		}
	}
</style>
